//class that represents a binary LFSR
//the maximum length of the LFSR is 32-bits
//The implementation uses the following formula to create a new bit
//(this will explain the feedback notation)
//sL=state[L-1]poly[L-1]+state[L-2]poly[L-2]+ ... + state[0]poly[0]
//thus the term x[L] is not needed in the representation
#ifndef lfsr32_h
#define lfsr32_h

#include "word32.h"

class lfsr32{

private:
  int L ; 
  word32 state; 
  word32 poly;

public:
  //default constructor set the length to 32
  lfsr32(){
    L=32;
  }

  //initiate with given length
  lfsr32(int length){
    L=length;
  }

  //set the initial state with another word32
  //the length is not changed
  void initState(word32 init){
    state.assign(init);
  }

  //set the initial state with a binary string, LSB first
  //the length is set to the length of the initString
  void initState(std::string initString){
    L=initString.length();
    state.assign(initString);
  }

  //set the initial state with a unsigned long, assumes MSB first
  //the length is not changed
  void initState(unsigned long initLong){
    state.assign(initLong);
  }

  //set the feedback polynomial using a word32
  //the length of the LFSR is not changed
  void initPoly(word32 newPoly){
    poly.assign(newPoly);
  }

  //set the feedback polynomial using a binary string, LSB first
  //the length is set to the length of the initString
  void initPoly(std::string polyString){
    L=polyString.length();
    poly.assign(polyString);
  }

  //set the feedback polynomial using an unsigned long, MSB first
  //the length of the LFSR is not changed
  void initPoly(unsigned long longPoly){
    poly.assign(longPoly);
  }

  //change the length of th LFSR
  void resize(int newL){
    L=newL;
  }

  //return the length
  int getLength(){
    return L;
  }

  //return the state
  word32 getState(){
    return state;
  }

  //return the feedback polynomial
  word32 getPoly(){
    return poly;
  }

  //step the LFSR one time
  int clock();
  
  //step the LFSR 32 times
  word32 clock32();

};

#endif
